package cn.anecansaitin.firecrafting.common.event;

import cn.anecansaitin.firecrafting.ModConstant;
import cn.anecansaitin.firecrafting.common.crafting.ModRecipeTypes;
import cn.anecansaitin.firecrafting.common.world.FireCraftingSavedData;
import cn.anecansaitin.firecrafting.api.common.crafting.IFireRecipe;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.entity.EntityLeaveWorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.ForgeRegistries;
import vazkii.botania.api.internal.IManaBurst;

import java.util.List;
import java.util.Objects;

//将被烧掉的物品存入SavedData中记录，并进行物品合成
//思路：当物品被火燃烧销毁，则存入世界数据保存（SavedData）。
//  每次成功保存后进行一次配方检测，检测成功，生成对应产物
//  并将存储的物品数据删除。
//判断物品是否被火焰销毁方式：当实体离开世界，判断该实体是否为
//  物品实体（ItemEntity），判断实体是否在燃烧状态，检测周围是
//  否存在火焰。
@Mod.EventBusSubscriber(modid = ModConstant.MOD_ID)
public class ItemBurnedEvent {
    @SubscribeEvent
    public static void itemBurnedEvent(EntityLeaveWorldEvent event) {
        //获取实体
        Entity entity = event.getEntity();
        //获取实体所处世界
        Level world = event.getWorld();
        //判断在服务端且为物品实体
        if (!world.isClientSide() && entity instanceof ItemEntity itemEntity) {
            //检测物品被烧掉并且不为合成产物
            if (itemEntity.wasOnFire && !itemEntity.getTags().contains(IFireRecipe.TYPE_ID)) {
                //以下为获取火的坐标
                //由于物品坐标不完全与火焰坐标一致，因此需要在物品坐标附近进行搜索
                //获取物品坐标（所在方块坐标，无小数）
                BlockPos pos = itemEntity.blockPosition();
                //获取精确的物品坐标（带小数）
                Vec3 position = itemEntity.position();
                //获取精确x值
                double x = position.x();
                //获取精确z值
                double z = position.z();
                //用于标记物品靠进当前方块的东面或西面
                int xs;
                //用于标记物品靠进当前方块的南面或北面
                int zs;
                //用于标记是否有找到火方块
                boolean fire = false;
                //物品精确坐标减去坐标四舍五入后的值与零比较
                xs = x - (x < 0 ? - Math.round(-x) : Math.round(x)) > 0 ? -1 : 1;
                zs = z - (z < 0 ? - Math.round(-z) : Math.round(z)) > 0 ? -1 : 1;
                //将所有可能要检测的方块坐标放入集合
                BlockPos[] poss = new BlockPos[]{pos, pos.east(xs), pos.south(zs), pos.offset(xs, 0, zs)};
                //遍历寻找火方块
                for (BlockPos checkPos : poss) {
                    //获取坐标位置方块信息
                    BlockState state = world.getBlockState(checkPos);
                    //判断方块是否继承自BaseFireBlock
                    if (state.getBlock() instanceof BaseFireBlock) {
                        //设置最终坐标为被检测坐标
                        pos = checkPos;
                        //将fire设为true，标记为找到
                        fire = true;
                        //跳出遍历
                        break;
                    }
                }
                //如果找到了火进行行为
                if (fire) {
                    //获取世界数据存储FireCraftingSavedData
                    FireCraftingSavedData data = FireCraftingSavedData.getInstance((ServerLevel) world);
                    //物品存入data中
                    if (!data.addItem(pos, itemEntity.getItem())) {
                        //无法存入直接结束
                        return;
                    }
                    //对该坐标保存的物品进行配方检测
                    List<IFireRecipe> recipeList = world.getRecipeManager().getAllRecipesFor(ModRecipeTypes.FIRE_TYPE.get());
                    //遍历配方进行检测
                    for (IFireRecipe recipe : recipeList) {
                        //检测成功并生成产物
                        if (recipe.doAction(data.getStacks(pos), pos, world)) {
                            //从dataSave中删除坐标物品
                            data.removeByPos(pos);
                            break;
                        }
                    }
                }
            }
        }
    }
}
